package com.kasa.zto;


/**
 * <p>Title: </p>
 *
 * <p>Description: 编码器</p>
 *
 * <p>Copyright: Copyright (c) 2008</p>
 *
 * <p>Company: </p>
 *
 * @author gary
 * @version 1.0
 */
public class SOSEncoder extends ZTOEncoder
{
    private volatile byte[] data;
    private byte[] validBytes;
    private int pos;

    public SOSEncoder()
    {
        setInitialCapacity(100);
    }

    public SOSEncoder(int initialCapacity)
    {
        setInitialCapacity(initialCapacity);
    }
    
    public int getLength()
    {
        return pos;
    }
    
    public void setInitialCapacity(int initialCapacity)
    {
        this.data = new byte[initialCapacity];
        
        this.validBytes = null;
        this.pos = 0;
    }
    
    protected void ensureCapacity(int minCapacity)
    {
        int oldLength = data.length;
        if (oldLength < minCapacity)
        {
            byte[] newData = new byte[minCapacity + minCapacity];
            System.arraycopy(data, 0, newData, 0, oldLength);
            data = newData;
        }
    }
    
    public byte[] getBytesData()
    {
        if (null == validBytes)
        {
            byte[] validBytes = new byte[pos];
            System.arraycopy(data, 0, validBytes, 0, pos);
            data = null;
            this.validBytes = validBytes;
        }

        return validBytes;
    }
    
    /**
     * 父类的方式，速度较慢，故重写
     */
    @Override
    protected void putByte(byte b)
    {
        ensureCapacity(pos + 1);
        data[pos++] = b;
    }

    protected void putBytes(byte[] bs)
    {
        int sLength = bs.length;
        ensureCapacity(pos + sLength);
        System.arraycopy(bs, 0, data, pos, sLength);
        pos += sLength;
    }
    
    /**
     * 将数字l编码成digit个字节，字节数决定n的范围，如下:
     * 对应的解码方法是Decoder.decodeNumber(int digit)
     * 1 byte -128~127
     * 2 byte -32768~32767
     * 3 byte -8388608~8388607
     * 4 byte -2147483648~2147483647
     * 5 byte -549755813888~549755813887
     * 6 byte -140737488355328~140737488355327
     * 7 byte -36028797018963968~36028797018963967
     * 8 byte -9223372036854775808~9223372036854775807
     */   
    public void encode_long(long l, byte digit) throws ZTOException
    {
    	long abs_l = Math.abs(l);
        byte[] bytes = new byte[digit];
        for (int i = 0; i < digit; i++)
        {
            bytes[i] = (byte) (abs_l >> 8 * (digit - i - 1));
        }
        
        putBytes(bytes);
    }
}
